package org.nativejpa.mapping;

import org.nativejpa.support.sqlgen.SQLGenerator;

import java.lang.reflect.Field;
import java.util.Collection;

/**
 * \@MappingColumn field
 * 
 * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
 * @create May 2, 2008 2:17:25 PM
 */
public class JoinColumnMetadata extends ColumnMetadata {

    /**
     * SQL for creating mapping sql
     */
    private String columnDefinition;

    /**
     * referenced column name, used to create mapping sql automatically
     */
    private String referencedColumnName;

    private boolean toMany = false;
    /**
     * 在 OneToMany, ManyToMany，要由 OneToMany.tagetEntity 指定 resultClass, 或者取 List Set 的泛型
     */
    private Class targetEntity;

    public JoinColumnMetadata() {
    }

    public String getColumnDefinition() {
        return columnDefinition;
    }

    public boolean isJoinColumn() {
        return true;
    }

    public void setColumnDefinition(String columnDefinition) {
        this.columnDefinition = columnDefinition;
    }

    public String getReferencedColumnName() {
        return referencedColumnName;
    }

    public void setReferencedColumnName(String referencedColumnName) {
        this.referencedColumnName = referencedColumnName;
    }

    public String getReferencedTableName() {
        return SQLGenerator.getTableName(getTargetEntity());
    }

    public Class<?> getTargetEntity() {
        return targetEntity;
    }

    public void setTargetEntity(Class targetEntity) {
        this.targetEntity = targetEntity;
    }

    public boolean isToMany() {
        return toMany;
    }

    @Override
    public void setField(Field field) {
        super.setField(field);
        if(getFieldType().isArray() || Collection.class.isAssignableFrom(getFieldType())) {
            toMany = true;
        }
    }

    @Override
    public void setFieldValue(Object entity, Object value) {
        if(isToMany() && getFieldType().isArray()) { //convert to array from List value
            value = ((Collection)value).toArray();
        }
        super.setFieldValue(entity, value);
    }

    public Object getReferenceValue(Object referencedObject) {
        return EntityRepository.getInstance().getEntityMetadata(getTargetEntity()).getColumnMetadata(referencedColumnName).getFieldValue(referencedObject);
    }
}
